package cn.sytton.taffe.framework.log;

import cn.sytton.taffe.framework.annotation.DisabledLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 日志记录类
 *
 * @author skyrock
 */
@Slf4j
@Component
public class LogWriter implements InitializingBean {

    private final ILogRecord logRecord;

    public LogWriter(@Nullable ILogRecord logRecord) {
        this.logRecord = logRecord;
    }

    public void logBegin(HttpServletRequest request, Object handler){
        if (logRecord == null){
            return;
        }
        try {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method =  handlerMethod.getMethod();
            DisabledLog disabledLog = method.getAnnotation(DisabledLog.class);
            if (disabledLog != null && disabledLog.disabled()) {
                return;
            }
            LogHelper.setData(logRecord.begin(method, request, handler));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public void logEnd(Object result) {
        if (logRecord == null){
            return;
        }
        String data = LogHelper.getData();
        if (StringUtils.hasText(data)) {
            record(data, result);
        }
    }

    @Async("logThreadExecutor")
    void record(String data, Object result) {
        assert logRecord != null;
        logRecord.end(data, result);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (logRecord == null) {
            log.warn("logRecord is null");
        }
    }
}
